package com.hyperf.core.lock.executor;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author lizhaoyang
 */
public class RedissonLockExecutor extends AbstractLockExecutor<RLock> {

    private static final String LOCK_KEY_PREFIX = "lock::";

    private RedissonClient redissonClient;

    public RedissonLockExecutor(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    @Override
    public RLock acquire(String lockKey, String lockValue, long expire, long acquireTimeout) {
        RLock lockInstance = redissonClient.getLock(LOCK_KEY_PREFIX + lockKey);
        try {
            boolean locked = lockInstance.tryLock(acquireTimeout, expire, TimeUnit.MILLISECONDS);
            return obtainLockInstance(locked, lockInstance);
        } catch (InterruptedException e) {
            return null;
        }
    }

    @Override
    public boolean releaseLock(String lockKey, String lockValue, RLock lockInstance) {
        if (lockInstance.isHeldByCurrentThread()) {
            try {
                return lockInstance.forceUnlockAsync().get();
            } catch (ExecutionException | InterruptedException e) {
                return false;
            }
        }
        return false;
    }
}
